package com.surendra.vendingmachine.unittest;
import static org.junit.Assert.*;
import junit.framework.Assert;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;



public class VendingMachineTest {
private VendingMachine machine;

private VendingMachineItem item1, item2;
	

	@Before
	public void setUp() throws Exception {
		 machine= new VendingMachine();
	
		 item1= new VendingMachineItem(" chocolate",1.00);
		 item2= new VendingMachineItem("rolls", 1.25);
	}

	@After
	public void tearDown() throws Exception {
		machine=null;
		item1= null;
		item2=null;
	}

	@Test
	/**
	 * we will add item1 to the vending machine slot A
	 * and check whether item added is in that slot
	 */
	public void testAddItem() {
	machine.addItem(item1, VendingMachine.A_CODE);
	assertEquals(item1,machine.getItem(VendingMachine.A_CODE));
	
	}
	@Test(expected=VendingMachineException.class)
	/**
	 * checking for wrong slot
	 */
	public void getSlotIndexTest(){
		String F_CODE="f";
		machine.addItem(item1, F_CODE);
		}
	@Test(expected=VendingMachineException.class)
	/*
	 * checking for vending machine exception when the slot is full
	 */
	public void addItemInOccupiedPlaceTest(){
		
		for(int i=0; i<4;i++){
		machine.addItem(item2, VendingMachine.B_CODE);
		}
		
		 machine.addItem(item2, VendingMachine.B_CODE);
	
	}@Test(expected=VendingMachineException.class)
	/*
	 * checking for slot that is null
	 */
	
	public void removeItemTest(){
		
		machine.removeItem(VendingMachine.D_CODE);
	}@Test(expected=VendingMachineException.class)
	/*
	 * checking for money less than zero
	 */
	public void insertMoneyTest(){
		
		machine.insertMoney(-2.00);
		machine.insertMoney(2.00);
		assertEquals(machine.getBalance(),2.00,0.001);
	}
			
		
	
	@Test
	/**
	 * first we will add an item2 to slot B and remove it
	 * and then check whether that slot has null value
	 */
	public void testRemoveItem() {
		machine.addItem(item2, VendingMachine.B_CODE);
		machine.removeItem(VendingMachine.B_CODE);
		assertTrue(machine.getItem(VendingMachine.B_CODE)==null);
		
	}

	@Test
	/**
	 * first we will insert the money and see whether inserted
	 * money plus balance is equal to the given total balance
	 * equal to 3 decimal places
	 */
	public void testInsertMoney() {
		final double myMoney=5.00;
		machine.insertMoney(myMoney);
		assertEquals(5.00,machine.getBalance(),0.001);
		
	}

	@Test
	/**
	 * first check the initial balance which is zero
	 * 
	 */
	public void testGetBalance() {
		assertEquals(0.00, machine.getBalance(),0.001);
	}
	@Test
	/**
	 * test after inserting money twice to see whether
	 * balance gets accumulated or not
	 */
	public void testGetBalanceAfterInsertingMoney(){
		machine.insertMoney(8.00);
		machine.insertMoney(20.00);
		assertEquals(28.00,machine.getBalance(),0.001);
		
	}

	@Test
	/**
	 * check whether change is returned after purchase
	 */
	public void testReturnChange() {
		machine.addItem(item2, VendingMachine.D_CODE);
		machine.insertMoney(10.00);
		machine.makePurchase(VendingMachine.D_CODE);
		assertEquals(8.75, machine.returnChange(),0.001);
		
	}
	@Test
	/**
	 * checks whether item is removed after purchase
	 * first add item, purchase it and see whether the vending
	 * machine is empty or has null after the purchase
	 */
	public void makePurchase(){
		machine.addItem(item1, VendingMachine.A_CODE);
		machine.insertMoney(8.00);
		machine.makePurchase(VendingMachine.A_CODE);
		assertNull(machine.getItem(VendingMachine.A_CODE));
	}
	@Test
	/**
	 *  checks make sure if the amount is less than cost price, no one can purchase it
	 *  the item should be still in the slot
	 */
	public void cannotMakePurchaseTest(){
		machine.addItem(item2, VendingMachine.D_CODE);
		machine.insertMoney(0.50);
		machine.makePurchase(VendingMachine.D_CODE);
		assertNotNull(machine.getItem(VendingMachine.D_CODE));
		/**
		 * if item is null and balance less than price
		 */
		item1=null;
		machine.addItem(item1, VendingMachine.C_CODE);
		machine.insertMoney(0.50);
		machine.makePurchase(VendingMachine.C_CODE);
		
		
		
		
		
		
	}

}
